/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#ifndef _RENDERER_H_
#define _RENDERER_H_

/////////////////////////////////////////////////////////////////////////////////////
// Include Files
#include "Systems\Window.h"

/////////////////////////////////////////////////////////////////////////////////////
// Forward Declarations

// game
class CGame;

// managers
class CMeshManager;
class CShaderManager;
class CTextureManager;

// TODO: ???
class CWindow;
class CRenderState;
class CCamera;

// event arguments
class CMeshEventArg;
class CShaderLoadEventArg;
class CTextureEventArg;
class CRenderStateEventArg;

/////////////////////////////////////////////////////////////////////////////////////
// This class runs a thread which renders all registered render states.
class CRenderer : 
	public ISingleton<CRenderer>, public ABCProcess, public IListener
{
public:     // methods

	// Initialize the renderer.
	void Initialize();

	// Shut down the renderer.
	void Shutdown();

private:    // friend only methods
	friend class ISingleton<CRenderer>;

	CRenderer();
	~CRenderer() { }

private:    // event handlers

	void OnMeshLoad( CMeshEventArg &_rArg );
	void OnMeshUpdate( CMeshEventArg &_rArg );
	void OnShaderLoad( CShaderLoadEventArg &_rArg );
	void OnTextureLoad( CTextureEventArg &_rArg );

	// Called when a render state is added
	void OnRenderStateAdd( CRenderStateEventArg &_rArg );

	// Called when a render state is removed
	void OnRenderStateRemove( CRenderStateEventArg &_rArg );

	// Called when a render state is updated
	void OnRenderStateUpdate( CRenderStateEventArg &_rArg );

private:    // methods

	// Called when the process is started.
	void ProcessBegin();

	// Called when the process is stopped.
	void ProcessEnd();

	// Called at the frame rate with which the process was started.
	// _fTime: float_t - the seconds that have passed since the last tick
	void ProcessTick( float_t _fTime );

	// Handles Windows messages for the window
	static LRESULT CALLBACK WndProc( 
		HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

private:    // dummy definitions
	CRenderer( CRenderer const & );
	CRenderer & operator =( CRenderer const & );

private:    // data

	// assets
	CSingleton<CMeshManager>    m_pMeshManager;
	CSingleton<CShaderManager>  m_pShaderManager;
	CSingleton<CTextureManager> m_pTextureManager;

	// systems
	CSingleton<CWindow> m_pWindow;
	CSingleton<CGame>   m_pGame;

	// OpenGL handles
	HDC   m_hGLDevice;
	HGLRC m_hGLRender;

	// TODO: not sure where to put this, probably in CScene...
	CCamera *m_pCamera;

	// states to be rendered
	flist_t<CRenderState *> m_lstRenderStates;

	// TODO: remove/replace this
	void ReSizeGLScene(uint_t width, uint_t height);
};

/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#endif // _RENDERER_H_
